package com.game.service.impl;

import java.util.Date;
import java.util.Map;

import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.ws.rs.client.ClientBuilder;

import com.game.dao.IAccessTokenDao;
import com.game.dao.IGameDao;
import com.game.dao.IGameRoundDao;
import com.game.dao.IUserDao;
import com.game.pojo.AccessToken;
import com.game.pojo.User;
import com.game.pojo.message.TextMessage;
import com.game.service.IGameService;
import com.game.service.IMessageService;
import com.game.service.IUserService;
import com.game.util.AccessTokenUtil;
import com.game.util.GameUtils;
import com.game.util.HttpUtils;
import com.game.util.MessageUtils;
/**
 * 处理用户信息的service类
 * @author Administrator
 *
 */
@Stateless
@Local(IMessageService.class)
public class MessageService implements IMessageService {
	
	@EJB
	private IGameService gameService;
	@EJB
	private IUserService userService;
	@Inject private IUserDao userDao;
	@Inject private IGameDao gameDao;
	@Inject private IGameRoundDao gameRoundDao;
	@Inject private IAccessTokenDao accessTokenDao;
	//第一次想用全局变量，后来考虑到线程安全问题，目前先放弃
		//private static String respMessage = null;
		
		/**
		 * 处理微信服务器发来消息
		 */
		@Override
		public String processMessage(String message) {
			String respMessage = null;
			/*
			 * 微信发来的消息分为两个大类，消息和事件
			 */
			try{
				//将微信发来的消息封装为map
				Map<String,String> map = MessageUtils.parseXML(message);
				if(map.get("MsgType").equals(MessageUtils.REQ_MESSAGE_TYPE_EVENT)){
					//如果是事件，进行处理
					respMessage = processEvent(map,respMessage);
				}else{
					//如果是消息，进行处理
					respMessage = processNotEvent(map,respMessage);
				}
			}catch(Exception e){
				e.printStackTrace();
			}
			return respMessage;
		}
		
		/**
		 * 处理消息类型不是事件的处理
		 * @param map
		 */
		private String processNotEvent(Map<String, String> map,String respMessage) {
			// TODO Auto-generated method stub
			switch(map.get("MsgType")){
			case(MessageUtils.REQ_MESSAGE_TYPE_TEXT):
				//处理文本消息
				respMessage = processTextMessage(map,respMessage);
				break;
			case(MessageUtils.REQ_MESSAGE_TYPE_IMAGE):
				//处理图片消息
				break;
			case(MessageUtils.REQ_MESSAGE_TYPE_VOICE):
				//处理语音消息
				break;
			case(MessageUtils.REQ_MESSAGE_TYPE_VIDEO):
				//处理视频消息
				break;
			case(MessageUtils.REQ_MESSAGE_TYPE_SHORTVIDEO):
				//处理小视频消息
				break;
			case(MessageUtils.REQ_MESSAGE_TYPE_LINK):
				//处理链接消息
				break;
			case(MessageUtils.REQ_MESSAGE_TYPE_LOCATION):
				//处理地理位置消息
				break;
			}
			return respMessage;
		}
		
		/**
		 * 对用户发送的文本消息进行处理
		 * @param map
		 * @return 
		 */
		private String processTextMessage(Map<String, String> map,String respMessage) {
			//发送方账号
			String fromUserName = map.get("FromUserName");
			//接收方账号（公众号开发者）
			String toUserName = map.get("ToUserName");
			//发送文本消息的内容
			String reqContext = map.get("Content");
			
			//回复文本消息
			TextMessage textMessage = new TextMessage();
			textMessage.setToUserName(fromUserName);
			textMessage.setFromUserName(toUserName);
			textMessage.setCreateTime(new Date().getTime());
			textMessage.setMsgType(MessageUtils.RESP_MESSAGE_TYPE_TEXT);
			switch(reqContext){
			case("help") :
				textMessage.setContent(gameService.getGameRule());
				break;
			case("score") :
				textMessage.setContent(gameService.getUserScore(fromUserName));
				break;
			default :
				if(GameUtils.verifyNumber(reqContext) && !GameUtils.verifyRepeat(reqContext)){
					textMessage.setContent(gameService.processGame(fromUserName, reqContext));
				}else{
					textMessage.setContent("请您输入正确的命令哦");
				}
			}
			respMessage = MessageUtils.messageToXML(textMessage);
			return respMessage;
		}

		/**
		 * 处理消息类型为事件的消息
		 * @param map
		 * @param respMessage 
		 */
		private String processEvent(Map<String, String> map, String respMessage) {
			// TODO Auto-generated method stub
			/*
			 * 事件有一些几种：
			 * subscribe订阅
			 * unsubscribe取消订阅
			 * scan扫描带参数的二维码
			 * LOCATION上次位置
			 * CLICK点击自定义菜单
			 */
			switch(map.get("Event")){
			case("subscribe"):
				//处理订阅事件
				respMessage = processSubscribeEvent(map,respMessage);
				break;
			case("unsubscribe"):
				//处理取消订阅事件
				proceseUnSubscribeEvent(map,respMessage);
				break;
			case("SCAN"):
				//处理用户扫描带参数二维码事件
				break;
			case("LOCATION"):
				//处理用户上报地理位置事件
				break;
			case("CLICK"):
				//处理用户点击自定义菜单事件
				respMessage = processClickEvent(map,respMessage);
				break;
			}
			return respMessage;
		}
		
		/**
		 * 处理用户点击自定义菜单的事件
		 * @param map
		 * @param respMessage
		 */
		private String processClickEvent(Map<String, String> map, String respMessage) {
			TextMessage textMessage = new TextMessage();
			textMessage.setCreateTime(new Date().getTime());
			textMessage.setFromUserName(map.get("ToUserName"));
			textMessage.setMsgType("text");
			textMessage.setToUserName(map.get("FromUserName"));
			//自定义菜单事件有enventkey
			switch(map.get("EventKey")) {
			case("game-rule") :
				textMessage.setContent(gameService.getGameRule());
				break;
			case("new-game"):
				textMessage.setContent(gameService.startNewGame(map.get("FromUserName")));
				break;
			case("red-heart"):
				textMessage.setContent("你的点赞我已收到，非常感谢 /爱心");
				break;
			}
			respMessage = MessageUtils.messageToXML(textMessage);
			return respMessage;
		}

		/**
		 * 处理用户取消订阅事件
		 * @param map
		 * @param respMessage
		 */
		private void proceseUnSubscribeEvent(Map<String, String> map, String respMessage) {
			String openId = map.get("FromUserName");
			//从数据库删除用户
			//userDao.deleteUser(openId);
			
			
		}

		/**
		 * 处理订阅事件
		 * @param map
		 * @param respMessage 
		 */
		private String processSubscribeEvent(Map<String, String> map, String respMessage) {
			//本项目的 逻辑是，如果用户订阅本公众号，就给用户推送一条文本消息
			TextMessage textMessage = new TextMessage();
			textMessage.setContent(gameService.getGameRuleAndHead());
			textMessage.setCreateTime(new Date().getTime());
			textMessage.setFromUserName(map.get("ToUserName"));
			textMessage.setMsgType("text");
			textMessage.setToUserName(map.get("FromUserName"));
			//使用消息工具把textMessage转换成xml
			respMessage = MessageUtils.messageToXML(textMessage);
			
			//调用用户服务类，把用户保存到数据库
			userService.getUserInfo(map.get("FromUserName"));
			
			return respMessage;
			
		}
}
